org 900h

jmp CODE
[SECTION .data]
MemLen: dd 0

ARDSPtr:
%rep 10
	dd 0;BaseAddrLow
	dd 0;BaseAddrHigh
	dd 0;LengthLow
	dd 0;LenthHign
	dd 0;Type
%endrep

[SECTION .code]
[BITS 16]
CODE:
	mov ax, cs
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov sp, 0100h

	;Prepare for reading memory
	mov ax ,0xe820
	;mov ebx, 0
	xor ebx, ebx
	;mov es,  Cache
	mov di, ARDSPtr
	mov ecx, 20
	mov edx, 0x534d4150
	xor si, si;esi stores the number of ARDS.
.1:
	;Call in 0x15 to get the memory infomation.
	int 0x15
	;Some delay to wait for interuption.
	jc .m2;If CF=1,jump to .end.
	nop
	nop
	nop
	nop
	inc si
	add di, 20 ;di add 20 to let [es:di] store the next ARDS.
	cmp ebx, 0 ;ebx is 0 implies the last ARDS.
	jnz .1
.e:
	cmp si, 0
	jz .m2
	;Find the max BaseAddr+Length which means the memory.
	xor ebx, ebx;Reserve the max value.
	xor di, di
	mov cx, si
.max:
	mov eax, dword [ARDSPtr+di];Low bass address bits.
	mov edx, dword [ARDSPtr+di+8];Low length bits
	add eax, edx;BaseAddr+Length
	add di, 20
	cmp eax, ebx
	jng .notmove
	mov ebx, eax
.notmove:
	loop .max
	cmp ebx, 0
	jz .m2
	mov dword [MemLen], ebx
	jmp .end
.m2:
	mov ax, 0xe801;Call number 0xe801 of 0x15 interrupt 
	int 0x15
	jc .m3;If CF = 1,it means error occures,jump to method3.
	movzx eax, ax;Memory size below 16 mb.
	shl eax, 10;Unit is 1k,so multiply 1024,name as shift left 10 bits.
	movzx ebx, bx;Memory size beyond 16 mb.
	shl ebx, 16;Unit is 64k
	add ebx, eax
	add ebx, 0x100000;Add the hole of 1m.
	mov dword [MemLen], ebx
	jmp .end

.m3:
	mov ax, 0x88;Call number 0xe88 of 0x15 interrupt 
	int 0x15
	jc .end
	movzx eax, ax
	shl eax, 10
	add eax, 0x100000
	mov dword [MemLen], eax
.end:
	jmp $






